package javazoom.jlGui;

/*
 * Player.
 *
 *-----------------------------------------------------------------------
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *----------------------------------------------------------------------
 */

import java.awt.*;
import java.io.*;
import java.net.*;
import java.awt.event.*;
import javax.sound.sampled.*;
import javazoom.jlGui.skin.*;
import javazoom.jlGui.playlist.*;
import javazoom.Util.*;
/*
 * Player is the core of jlGui.<br>
 *
 * @author	E.B from JavaZOOM
 *
 * Homepage : http://www.javazoom.net
 */
public class Player extends Window implements ActionListener, BasicPlayerListener
{
	private String 		        currentFileOrURL = null;
    private String              currentSongName = null;
	private boolean		        currentIsFile;

    /*-- Window Parameters --*/
    private Image               offScreenImage;
    private Graphics            offScreenGraphics;
    private int                 WinWidth, WinHeight;
    private int                 OrigineX = 10, OrigineY = 10;
	private String		        thePath="";
	private String      		theMain="main.bmp";

	/*-- Buttons Panel members --*/
	private String		        theButtons="cbuttons.bmp";
	private Image		        imMain,imButtons;
	private activeComponent     acPrevious,acPlay,acPause,acStop,acNext,acEject;
	private Image	        	imPrevious,imPlay,imPause,imStop,imNext,imEject;
	private Image[]	        	releasedImage = {imPrevious,imPlay,imPause,imStop,imNext,imEject};
	private Image[]	        	pressedImage = {imPrevious,imPlay,imPause,imStop,imNext,imEject};
	private int[]	        	releasedPanel = {0,0,23,18, 23,0,23,18, 46,0,23,18, 69,0,23,18, 92,0,22,18, 114,0,22,16};
	private int[]	    	    pressedPanel  = {0,18,23,18, 23,18,23,18, 46,18,23,18, 69,18,23,18, 92,18,22,18, 114,16,22,16};
	private int[]               panelLocation = {16,88, 39,88, 62,88, 85,88, 108,88, 137,89};

    /*-- Title members --*/
	private boolean     		FirstDrag = true;
	private int                 XDrag = 0, YDrag = 0;
	private String		        theTitleBar="titlebar.bmp";
	private Image		        imTitleBar;
    private activeComponent     acTitleBar;
	private Image	        	imTitleB;
	private Image[]	        	releasedTitleIm = {imTitleB};
	private Image[]	        	pressedTitleIm = {imTitleB};
	private int[]	        	releasedTitlePanel = {27,0,264,14};
	private int[]	    	    pressedTitlePanel  = {27,15,264,14};
	private int[]               titleBarLocation = {0,0};

    private activeComponent     acExit;
	private int[]	        	releasedExitPanel = {18,0,9,9};
	private int[]	    	    pressedExitPanel  = {18,9,9,9};
	private Image[]	        	releasedExitIm = {null};
	private Image[]	        	pressedExitIm = {null};
	private int[]               exitLocation = {264,3};

	/*-- Text Members --*/
	private int                 fontWidth = 5;
	private int                 fontHeight = 6;
    private String              theText = "text.bmp";
	private Image               imText;
	private String              fontIndex =   "ABCDEFGHIJKLMNOPQRSTUVWXYZ\"@a  "
	                                        + "0123456789  :()-'!_+ /[]^&%.=$#"
	                                        + "   ?*";
    private Image               sampleRateImage;
    private String              sampleRateClearText = "  ";
    private Image               sampleRateClearImage;
    private int[]               sampleRateLocation = {156,43};
    private String              bitsRateClearText = "    ";
    private Image               bitsRateClearImage;
	private Image               bitsRateImage;
	private int[]               bitsRateLocation = {107,43};
	private String              TITLETEXT = "JLGUI 2.0";
	private String              titleText = TITLETEXT;
    private String              clearText = "                                     ";
    private Image               clearImage;
	private Image               titleImage;
	private int[]               titleLocation = {111,27};

	/*-- Numbers Members --*/
	private int                 numberWidth = 9;
	private int                 numberHeight = 13;
    private String              theNumbers = "numbers.bmp";
	private Image               imNumbers;
	private String              numberIndex = "0123456789 ";
    private Image               minuteImage;
    private Image               secondImage;
    private Image               minuteDImage;
    private Image               secondDImage;
    private Image[]             timeImage = {null,null,null,null,null,null,null,null,null,null,null};
    private int[]               minuteDLocation = {48,26};
    private int[]               minuteLocation = {60,26};
    private int[]               secondDLocation = {78,26};
    private int[]               secondLocation = {90,26};

	/*-- Mono/Stereo Members --*/
    private String              theMode = "monoster.bmp";
    private Image               imMode;
    private int[]	        	activeModePanel = {0,0,28,12, 29,0,27,12};
    private int[]	        	passiveModePanel = {0,12,28,12, 29,12,27,12};
    private Image               imSA,imMA,imSI,imMI;
    private Image[]             activeModeImage = {imSA,imMA};
    private Image[]             passiveModeImage = {imSI,imMI};
	private int[]               monoLocation = {212,40};
	private int[]               stereoLocation = {239,40};

	/*-- Volume/Balance Panel members --*/
	private boolean     		FirstVolumeDrag = true;
	private int                 XVolumeDrag = 0;
	private String		        theVolume="volume.bmp";
	private Image		        imVolume;
	private activeComponent     acVolume, acBalance;
	private Image[]	        	volumeImage = {null,null,null,null,null,null,null,
	                                           null,null,null,null,null,null,null,
	                                           null,null,null,null,null,null,null,
	                                           null,null,null,null,null,null,null};
    private String              fakeIndex = "abcdefghijklmnopqrstuvwxyz01";
	private int[]               volumeBarLocation = {107,57};
    private Image[]             releasedVolumeImage = {null};
    private Image[]	        	pressedVolumeImage = {null};
	private int[]	        	releasedVolumePanel = {15,422,14,11};
	private int[]	    	    pressedVolumePanel  = {0,422,14,11};
	private int     			minGain		= 0;
	private int			        maxGain		= 100;
    private int			        gainValue   = 80;
    private int                 deltaVolume = 50;
	private int[]               volumeLocation = {107+deltaVolume*gainValue/maxGain,58};
    private int[]               volumeBounds = {107,107+deltaVolume};

	private Image[]	        	balanceImage = {null};
	private boolean     		FirstBalanceDrag = true;
	private int                 XBalanceDrag = 0;
	private double     			minBalance	 = -1.0;
	private double		        maxBalance 	 = +1.0;
    private double		        balanceValue = 0.0;
   	private int                 deltaBalance = 24;
	private int[]               balanceLocation = {177+deltaBalance/2,58};
    private int[]               balanceBounds = {177,177+deltaBalance};
	private int[]               balanceBarLocation = {177,57};

    /*-- Play/Pause Icons --*/
	private String		        theIcons="playpaus.bmp";
	private Image		        imIcons;
	private Image[]	        	iconsImage = {null,null,null,null,null};
	private int[]	        	iconsPanel = {0,0,9,9 ,9,0,9,9, 18,0,9,9, 36,0,3,9, 27,0,2,9};
	private int[]               iconsLocation = {26,27, 24,27};


    /*-- PosBar members --*/
	private boolean     		FirstPosBarDrag = true;
	private int                 XPosBarDrag = 0;
	private String		        thePosBar="posbar.bmp";
	private Image		        imPosBar;
    private activeComponent     acPosBar;
	private Image[]	        	releasedPosIm = {null};
	private Image[]	        	pressedPosIm = {null};
	private int[]	        	releasedPosPanel = {248,0,28,10};
	private int[]	    	    pressedPosPanel  = {278,0,28,10};
	private double     			minPos = 0.0;
	private double		        maxPos = +1.0;
    private double		        posValue = 0.0;
   	private int                 deltaPosBar = 219;
	private int[]               posBarLocation = {16,72};
    private int[]               posBarBounds = {16,16+deltaPosBar};

	//private int[]               posBarLocation = {16,72};

    /*-- JavaSound Members --*/
    private static final int    INIT = 0;
    private static final int    OPEN = 1;
    private static final int    PLAY = 2;
    private static final int    PAUSE = 3;
    private static final int    STOP = 4;
	private int                 playerState =  INIT;
	private long                secondsAmount = 0;

	private Playlist         	playlist = null;
	private BasicPlayer         theSoundPlayer = null;
	private Config				config = null;

	/**
	 * Constructor.
	 */
	public Player(String Skin, int loglevel, String logfile)
	{
		super(new Frame());
		// Log feature.
		Debug dbg = Debug.getInstance();
		if ( (logfile != null) && (!logfile.equals("")) )
		{
			dbg.init(logfile, loglevel);
		}
		else dbg.setLogLevel(loglevel);
		// Config feature.
		config = Config.getInstance();
		// Skin feature.
		if (Skin != null) thePath = Skin;
		else thePath = config.getDefaultSkin();
		SkinLoader skl = new SkinLoader(thePath);
	    try
	    {
	    	 skl.loadImages();
	    } catch (Exception e)
	  	  {
			trace(0,getClass().getName(),"Can't load skin : "+e.getMessage());
			System.exit(0);
		  }

	    imMain = skl.getImage(theMain);
		imButtons = skl.getImage(theButtons);
		imTitleBar = skl.getImage(theTitleBar);
		imText = skl.getImage(theText);
		imMode = skl.getImage(theMode);
		imNumbers = skl.getImage(theNumbers);
		imVolume = skl.getImage(theVolume);
		imIcons = skl.getImage(theIcons);
		imPosBar = skl.getImage(thePosBar);

		WinHeight = imMain.getHeight(this);
		WinWidth = imMain.getWidth(this);
		setSize(WinWidth,WinHeight);
		setLocation(OrigineX,OrigineY);
		setBackground(Color.black);
		show();

      	offScreenImage = createImage(WinWidth,WinHeight);
	    offScreenGraphics = offScreenImage.getGraphics();
	    offScreenGraphics.drawImage(imMain,0,0,this);

		// Playlist feature.
		PlaylistFactory plf = PlaylistFactory.getInstance();
		playlist = plf.getPlaylist();
		playlist.load(config.getPlaylistFilename());

        theSoundPlayer = new BasicPlayer(this);

        /*-- Buttons --*/
        readPanel(releasedImage,releasedPanel,pressedImage,pressedPanel,imButtons);
        setButtonsPanel();

        /*-- Volume/Balance --*/
        readPanel(releasedVolumeImage,releasedVolumePanel,pressedVolumeImage,pressedVolumePanel,imVolume);
        setVolumePanel();

        /*-- Title Bar --*/
        readPanel(releasedTitleIm,releasedTitlePanel,pressedTitleIm,pressedTitlePanel,imTitleBar);
        setTitleBarPanel();

        /*-- Exit --*/
        readPanel(releasedExitIm,releasedExitPanel,pressedExitIm,pressedExitPanel,imTitleBar);
        setExitPanel();


        /*-- Mode --*/
        readPanel(activeModeImage,activeModePanel,passiveModeImage,passiveModePanel,imMode);
        offScreenGraphics.drawImage(passiveModeImage[0], stereoLocation[0], stereoLocation[1], this);
        offScreenGraphics.drawImage(passiveModeImage[1], monoLocation[0], monoLocation[1], this);

        /*-- Text --*/
        sampleRateClearImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, sampleRateClearText)).getBanner();
        bitsRateClearImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, bitsRateClearText)).getBanner();
        clearImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, clearText)).getBanner(0,0,155,6);
        titleImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, titleText)).getBanner(0,0,155,6);
        offScreenGraphics.drawImage(titleImage, titleLocation[0], titleLocation[1], this);

        /*-- Numbers --*/
        for (int h=0;h<numberIndex.length();h++)
        {
            timeImage[h] = (new taftb(numberIndex, imNumbers, numberWidth, numberHeight, 0, ""+numberIndex.charAt(h))).getBanner();
        }

        /*--  Icons --*/
        readPanel(iconsImage,iconsPanel,null,null,imIcons);
        offScreenGraphics.drawImage(iconsImage[2], iconsLocation[0], iconsLocation[1], this);

        /*-- Pos Bar --*/
        readPanel(releasedPosIm,releasedPosPanel,pressedPosIm,pressedPosPanel,imPosBar);
        setPosBarPanel();

        repaint();
	}

    /**
     * Crop Panel Features from image file.
     */
    private void readPanel(Image[] releasedImage, int[] releasedPanel,
                           Image[] pressedImage,  int[] pressedPanel, Image imPanel)
    {
       int xul,yul,xld,yld;
       int j = 0;
       if (releasedImage != null)
       {
           for (int i = 0; i<releasedImage.length; i++)
           {
                releasedImage[i] = createImage(releasedPanel[j+2],releasedPanel[j+3]);
                xul = releasedPanel[j];
                yul = releasedPanel[j+1];
                xld = releasedPanel[j] + releasedPanel[j+2];
                yld = releasedPanel[j+1] + releasedPanel[j+3];
		        (releasedImage[i].getGraphics()).drawImage(imPanel,0,0,releasedPanel[j+2],releasedPanel[j+3],
		                                                   xul,yul,xld,yld,null);
                j = j + 4;
	      }
       }
       j = 0;

       if (pressedImage != null)
       {
            for (int i = 0; i<pressedImage.length; i++)
            {
                pressedImage[i] = createImage(pressedPanel[j+2],pressedPanel[j+3]);
                xul = pressedPanel[j];
                yul = pressedPanel[j+1];
                xld = pressedPanel[j] + pressedPanel[j+2];
                yld = pressedPanel[j+1] + pressedPanel[j+3];
		        (pressedImage[i].getGraphics()).drawImage(imPanel,0,0,pressedPanel[j+2],pressedPanel[j+3],
		                                                   xul,yul,xld,yld,null);
                j = j + 4;
	        }
	   }
    }

    /**
     * Instantiate Buttons Panel with activeComponent.
     * Add them to window and ActionListener.
     */
    private void setButtonsPanel()
    {
        int l = 0;
        setLayout(null);
        acPrevious = new activeComponent(releasedImage[0],pressedImage[0],AWTEvent.MOUSE_EVENT_MASK);
        acPrevious.setLocation(panelLocation[l++],panelLocation[l++]);
        add(acPrevious);
        acPrevious.setActionCommand("Previous");
        acPrevious.addActionListener(this);

        acPlay =  new activeComponent(releasedImage[1],pressedImage[1],AWTEvent.MOUSE_EVENT_MASK);
        acPlay.setLocation(panelLocation[l++],panelLocation[l++]);
        add(acPlay);
        acPlay.setActionCommand("Play");
        acPlay.addActionListener(this);

        acPause =  new activeComponent(releasedImage[2],pressedImage[2],AWTEvent.MOUSE_EVENT_MASK);
        acPause.setLocation(panelLocation[l++],panelLocation[l++]);
        add(acPause);
        acPause.setActionCommand("Pause");
        acPause.addActionListener(this);

        acStop =  new activeComponent(releasedImage[3],pressedImage[3],AWTEvent.MOUSE_EVENT_MASK);
        acStop.setLocation(panelLocation[l++],panelLocation[l++]);
        add(acStop);
        acStop.setActionCommand("Stop");
        acStop.addActionListener(this);

        acNext =  new activeComponent(releasedImage[4],pressedImage[4],AWTEvent.MOUSE_EVENT_MASK);
        acNext.setLocation(panelLocation[l++],panelLocation[l++]);
        add(acNext);
        acNext.setActionCommand("Next");
        acNext.addActionListener(this);

        acEject =  new activeComponent(releasedImage[5],pressedImage[5],AWTEvent.MOUSE_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);
        acEject.setLocation(panelLocation[l++],panelLocation[l++]);
        add(acEject);
        acEject.setActionCommand("Eject");
        acEject.addActionListener(this);
    }

    /**
     * Instantiate Title Panel with activeComponent.
     * Add them to window and ActionListener.
     */
    private void setTitleBarPanel()
    {
        int l = 0;
        acTitleBar = new activeComponent(releasedTitleIm[0],pressedTitleIm[0],AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
        acTitleBar.setLocation(titleBarLocation[l++],titleBarLocation[l++]);
        add(acTitleBar);
        acTitleBar.setActionCommand("TitleBar");
        acTitleBar.addActionListener(this);
    }

    /**
     * Instantiate Exit Panel with activeComponent.
     * Add them to window and ActionListener.
     */
    private void setExitPanel()
    {
        int l = 0;
        acExit = new activeComponent(releasedExitIm[0],pressedExitIm[0],AWTEvent.MOUSE_EVENT_MASK);
        acExit.setLocation(exitLocation[l++],exitLocation[l++]);
        add(acExit);
        acExit.setActionCommand("Exit");
        acExit.addActionListener(this);
    }

    /**
     * Instantiate Volume/Balance Panel with activeComponent.
     * Add them to window and ActionListener.
     */
    private void setVolumePanel()
    {
        int l = 0;
        acVolume = new activeComponent(releasedVolumeImage[0],pressedVolumeImage[0],AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
        acVolume.setLocation(volumeLocation[l++],volumeLocation[l++]);
        add(acVolume);
        acVolume.setActionCommand("Volume");
        acVolume.addActionListener(this);
        for (int k=0;k<volumeImage.length;k++)
        {
            volumeImage[k] = (new taftb(fakeIndex, imVolume, 68, 13, 2, ""+fakeIndex.charAt(k))).getBanner();
        }
        offScreenGraphics.drawImage(volumeImage[(int)Math.round(((double)gainValue / (double)maxGain)*(volumeImage.length-1))], volumeBarLocation[0], volumeBarLocation[1], this);

		l = 0;
        acBalance = new activeComponent(releasedVolumeImage[0],pressedVolumeImage[0],AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
        acBalance.setLocation(balanceLocation[l++],balanceLocation[l++]);
        add(acBalance);
        acBalance.setActionCommand("Balance");
        acBalance.addActionListener(this);
		balanceImage[0] = (new taftb("a", imVolume, deltaBalance+14, 13, 2, "a")).getBanner();
		offScreenGraphics.drawImage(balanceImage[0], balanceBarLocation[0], balanceBarLocation[1], this);

    }

    /**
     * Instantiate PosBar Panel with activeComponent.
     * Add them to window and ActionListener.
     */
    private void setPosBarPanel()
    {
        int l = 0;
        acPosBar = new activeComponent(releasedPosIm[0],pressedPosIm[0],AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
        acPosBar.setLocation(posBarLocation[l++],posBarLocation[l++]);
        add(acPosBar);
        acPosBar.setActionCommand("Seek");
        acPosBar.addActionListener(this);
        remove(acPosBar);
    }

	/**
	 * Sets the current song to play and start playing if needed.
	 */
	private void setCurrentSong(PlaylistItem pli)
	{
		int playerStateMem = playerState;
        if ( (playerState == PAUSE) || (playerState == PLAY) )
        {
			theSoundPlayer.stopPlayback();
            playerState = STOP;
            secondsAmount = 0;
            acPosBar.setLocation(posBarBounds[0],posBarLocation[1]);
            offScreenGraphics.drawImage(iconsImage[2], iconsLocation[0], iconsLocation[1], this);
			offScreenGraphics.drawImage(iconsImage[4], iconsLocation[2], iconsLocation[3], this);
        }
        playerState = OPEN;
		if (pli != null)
		{
			currentSongName = pli.getName();
			currentFileOrURL = pli.getLocation();
			currentIsFile = pli.isFile();
		}
		else
		{
			currentSongName = TITLETEXT;
			currentFileOrURL = null;
			currentIsFile = false;
		}
		if (currentIsFile == true)
		{
			add(acPosBar);
		}
		else
		{
			config.setLastURL(currentFileOrURL);
			remove(acPosBar);
		}
        titleText = currentSongName.toUpperCase();
        titleImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, titleText)).getBanner(0,0,155,6);
        offScreenGraphics.drawImage(clearImage, titleLocation[0], titleLocation[1], this);
        offScreenGraphics.drawImage(titleImage, titleLocation[0], titleLocation[1], this);
        offScreenGraphics.drawImage(sampleRateClearImage, sampleRateLocation[0], sampleRateLocation[1], this);
        offScreenGraphics.drawImage(bitsRateClearImage,bitsRateLocation[0], bitsRateLocation[1], this);
        offScreenGraphics.drawImage(passiveModeImage[0], stereoLocation[0], stereoLocation[1], this);
        offScreenGraphics.drawImage(passiveModeImage[1], monoLocation[0], monoLocation[1], this);
        offScreenGraphics.drawImage(timeImage[0], minuteDLocation[0], minuteDLocation[1], this);
        offScreenGraphics.drawImage(timeImage[0], minuteLocation[0], minuteLocation[1], this);
        offScreenGraphics.drawImage(timeImage[0], secondDLocation[0], secondDLocation[1], this);
        offScreenGraphics.drawImage(timeImage[0], secondLocation[0], secondLocation[1], this);
        repaint();
        // Start playing if needed.
        if ((playerStateMem == PLAY) || (playerStateMem == PAUSE))
        {
			acPlay.fireEvent();
		}
	}

    /*-----------------------------------------*/
    /*--    BasicPlayerListener Interface    --*/
    /*-----------------------------------------*/

	/**
	 * BasicPlayerListener implementation.
	 * It manages "elapsed time" event.
	 */
    public void updateCursor(int secondsAmount, int total)
    {
        /*-- Display elapsed time --*/
        //secondsAmount++;
        int      secondD,second,minuteD,minute;
        int      minutes = (int) (secondsAmount/60);
        int      seconds = (int) (secondsAmount - (minutes*60));
        if (seconds < 10)
        {
            secondD = 0;
            second = seconds;
        }
        else
        {
            secondD = ((int) seconds/10);
            second = ((int) (seconds - (((int) seconds/10))*10));
        }
        if (minutes < 10)
        {
            minuteD = 0;
            minute = minutes;
        }
        else
        {
            minuteD = ((int) minutes/10);
            minute = ((int) (minutes - (((int) minutes/10))*10));
        }
        // Update PosBar location.
        if (total != 0)
        {
			if (FirstPosBarDrag == true)
        	{
        		posBarLocation[0] = ((int) Math.round(secondsAmount*deltaPosBar/total)) + posBarBounds[0];
        		acPosBar.setLocation(posBarLocation[0],posBarLocation[1]);
			}
		}
		else posBarLocation[0] = posBarBounds[0];
        offScreenGraphics.drawImage(timeImage[minuteD], minuteDLocation[0], minuteDLocation[1], this);
        offScreenGraphics.drawImage(timeImage[minute], minuteLocation[0], minuteLocation[1], this);
        offScreenGraphics.drawImage(timeImage[secondD], secondDLocation[0], secondDLocation[1], this);
        offScreenGraphics.drawImage(timeImage[second], secondLocation[0], secondLocation[1], this);
        repaint();
    }

	/**
	 * BasicPlayerListener implementation.
	 * It manages End Of Media event.
	 */
	public void updateMediaState(String state)
	{
        /*-- End Of Media reached --*/
		if (state.equals("EOM"))
		{
	        if ( (playerState == PAUSE) || (playerState == PLAY) )
	        {
	           	playlist.nextCursor();
	           	PlaylistItem pli = playlist.getCursor();
				this.setCurrentSong(pli);
			}
		}
	}


	/**
	 * BasicPlayerListener implementation.
	 */
	public void updateMediaData(byte[] data)
	{
		// Spectrum analyzer could take place here
	}


    /**
     * Manages events.
     */
    public void actionPerformed( ActionEvent e )
    {
        /*------------------------------------*/
        /*--        Interact on Seek        --*/
        /*------------------------------------*/
        if (e.getActionCommand().equals("Seek"))
        {
            if (acPosBar.isMousePressed() == false)
			{
				FirstPosBarDrag = true;
				try
				{
					theSoundPlayer.setSeek(posValue);
				} catch (IOException ioe)
				  {
					  ioe.printStackTrace();
				  }
				repaint();
			}
            else
            {
        		int DeltaX = 0;
	        	if (FirstPosBarDrag == false)
	        	{
	    	    	DeltaX = acPosBar.getMouseX() - XPosBarDrag;
	    		    XPosBarDrag = acPosBar.getMouseX() - DeltaX;
	    		    if (posBarLocation[0]+DeltaX < posBarBounds[0]) posBarLocation[0] = posBarBounds[0];
	    		    else if (posBarLocation[0]+DeltaX  > posBarBounds[1]) posBarLocation[0] = posBarBounds[1];
	    		    else posBarLocation[0] = posBarLocation[0] + DeltaX;
		    	    acPosBar.setLocation(posBarLocation[0],posBarLocation[1]);
                    double a = (maxPos-minPos)/(posBarBounds[1] - posBarBounds[0]);
                    posValue = (a*(posBarLocation[0] - posBarBounds[0]) + minPos);
		        }
    		    else
	    	    {
		        	FirstPosBarDrag = false;
		        	XPosBarDrag = acPosBar.getMouseX();
	    	    }
	    	}
        }

        /*------------------------------------*/
        /*--       Interact on Volume       --*/
        /*------------------------------------*/
        else if (e.getActionCommand().equals("Volume"))
        {
            if (acVolume.isMousePressed() == false)
			{
				FirstVolumeDrag = true;
		        offScreenGraphics.drawImage(clearImage, titleLocation[0], titleLocation[1], this);
	            offScreenGraphics.drawImage(titleImage, titleLocation[0], titleLocation[1], this);
				repaint();
			}
            else
            {
        		int DeltaX = 0;
	        	if (FirstVolumeDrag == false)
	        	{
	    	    	DeltaX = acVolume.getMouseX() - XVolumeDrag;
	    		    XVolumeDrag = acVolume.getMouseX() - DeltaX;
	    		    if (volumeLocation[0]+DeltaX < volumeBounds[0]) volumeLocation[0] = volumeBounds[0];
	    		    else if (volumeLocation[0]+DeltaX  > volumeBounds[1]) volumeLocation[0] = volumeBounds[1];
	    		    else volumeLocation[0] = volumeLocation[0] + DeltaX;
		    	    acVolume.setLocation(volumeLocation[0],volumeLocation[1]);
                    double a = (maxGain-minGain)/(volumeBounds[1] - volumeBounds[0]);
                    gainValue = (int) (a*(volumeLocation[0] - volumeBounds[0]) + minGain);
		    		if (gainValue == 0) theSoundPlayer.setGain( 0 );
			        else theSoundPlayer.setGain(((double)gainValue / (double)maxGain) );
                    String volumeText = "VOLUME: "+(int) Math.round((100/(volumeBounds[1] - volumeBounds[0]))*(volumeLocation[0] - volumeBounds[0]))+"%";
                    Image volImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, volumeText)).getBanner();
                    offScreenGraphics.drawImage(volumeImage[(int)Math.round(((double)gainValue / (double)maxGain)*(volumeImage.length-1))], volumeBarLocation[0], volumeBarLocation[1], this);
                    offScreenGraphics.drawImage(clearImage, titleLocation[0], titleLocation[1], this);
                    offScreenGraphics.drawImage(volImage, titleLocation[0], titleLocation[1], this);
		        }
    		    else
	    	    {
		        	FirstVolumeDrag = false;
		        	XVolumeDrag = acVolume.getMouseX();
	    	    }
	    	}
        }

        /*------------------------------------*/
        /*--       Interact on Balance       --*/
        /*------------------------------------*/
        else if (e.getActionCommand().equals("Balance"))
        {
            if (acBalance.isMousePressed() == false)
			{
				FirstBalanceDrag = true;
				offScreenGraphics.drawImage(clearImage, titleLocation[0], titleLocation[1], this);
             	offScreenGraphics.drawImage(titleImage, titleLocation[0], titleLocation[1], this);
				repaint();
			}
            else
            {
        		int DeltaX = 0;
	        	if (FirstBalanceDrag == false)
	        	{
	    	    	DeltaX = acBalance.getMouseX() - XBalanceDrag;
	    		    XBalanceDrag = acBalance.getMouseX() - DeltaX;
	    		    if (balanceLocation[0]+DeltaX < balanceBounds[0]) balanceLocation[0] = balanceBounds[0];
	    		    else if (balanceLocation[0]+DeltaX  > balanceBounds[1]) balanceLocation[0] = balanceBounds[1];
	    		    else balanceLocation[0] = balanceLocation[0] + DeltaX;
		    	    acBalance.setLocation(balanceLocation[0],balanceLocation[1]);
                    double a = (maxBalance-minBalance)/(balanceBounds[1] - balanceBounds[0]);
                    balanceValue = (a*(balanceLocation[0] - balanceBounds[0]) + minBalance);
		    		theSoundPlayer.setPan((float)balanceValue);
                    String balanceText = "BALANCE: " + (int) Math.abs(balanceValue*100) + "%";
					if (balanceValue > 0) balanceText = balanceText + " RIGHT";
					else if (balanceValue < 0)  balanceText = balanceText + " LEFT";
					else  balanceText = "BALANCE: CENTER";
                    Image balImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, balanceText)).getBanner();
                    offScreenGraphics.drawImage(balanceImage[0], balanceBarLocation[0], balanceBarLocation[1], this);
                    offScreenGraphics.drawImage(clearImage, titleLocation[0], titleLocation[1], this);
                    offScreenGraphics.drawImage(balImage, titleLocation[0], titleLocation[1], this);
		        }
    		    else
	    	    {
		        	FirstBalanceDrag = false;
		        	XBalanceDrag = acBalance.getMouseX();
	    	    }
	    	}
        }

        /*------------------------------------*/
        /*-- Select Filename or URL to load --*/
        /*------------------------------------*/
        else if (e.getActionCommand().equals("Eject"))
        {
            if ((playerState == PLAY) || (playerState == PAUSE))
            {
                theSoundPlayer.stopPlayback();
                playerState = STOP;
            }
            if ((playerState == INIT) || (playerState == STOP) || (playerState == OPEN))
            {
				System.gc();
				PlaylistItem pli = null;
				// Local File.
				if (acEject.getMouseButton() == MouseEvent.BUTTON1_MASK)
				{
                	FileDialog FD = new FileDialog(new Frame(),"Open file",FileDialog.LOAD);
                	FD.show();
                	if (FD.getFile() != null) pli = new PlaylistItem(FD.getFile(), FD.getDirectory()+FD.getFile(), -1, true);
				}
				// Remote File.
				else if (acEject.getMouseButton() == MouseEvent.BUTTON3_MASK)
				{
					UrlDialog UD = new UrlDialog("Open location",100,100,280,120,config.getLastURL());
					UD.show();
                	if (UD.getFile() != null) pli = new PlaylistItem(UD.getFile(), UD.getURL(), -1, false);
				}
                this.setCurrentSong(pli);
            }
            offScreenGraphics.drawImage(iconsImage[2], iconsLocation[0], iconsLocation[1], this);
			offScreenGraphics.drawImage(iconsImage[4], iconsLocation[2], iconsLocation[3], this);
            repaint();
        }

        /*---------------------------*/
        /*-- Play the current File --*/
        /*---------------------------*/
        else if (e.getActionCommand().equals("Play"))
        {
            if (playerState == PAUSE)
            {
                theSoundPlayer.resumePlayback();
                playerState = PLAY;
                offScreenGraphics.drawImage(iconsImage[0], iconsLocation[0], iconsLocation[1], this);
                offScreenGraphics.drawImage(iconsImage[3], iconsLocation[2], iconsLocation[3], this);
                repaint();
            }
            else if (playerState == PLAY)
            {
                theSoundPlayer.stopPlayback();
                playerState = PLAY;
				secondsAmount = 0;
                offScreenGraphics.drawImage(timeImage[0], minuteDLocation[0], minuteDLocation[1], this);
                offScreenGraphics.drawImage(timeImage[0], minuteLocation[0], minuteLocation[1], this);
                offScreenGraphics.drawImage(timeImage[0], secondDLocation[0], secondDLocation[1], this);
                offScreenGraphics.drawImage(timeImage[0], secondLocation[0], secondLocation[1], this);
				repaint();
				if (currentFileOrURL != null)
				{
                	try
                	{
						if (currentIsFile == true) theSoundPlayer.setDataSource(openFile(currentFileOrURL));
						else theSoundPlayer.setDataSource(new URL(currentFileOrURL));
					} catch (Exception ex)
					  {
						   trace(0,getClass().getName(),"Cannot read file : "+currentFileOrURL+", "+ex.getMessage());
					  }
                	theSoundPlayer.startPlayback();
				}
            }
            else if ( (playerState == STOP) || (playerState == OPEN))
            {
            	if (currentFileOrURL != null)
            	{
            		try
                	{
						if (currentIsFile == true) theSoundPlayer.setDataSource(openFile(currentFileOrURL));
						else theSoundPlayer.setDataSource(new URL(currentFileOrURL));
					} catch (UnsupportedAudioFileException uafe)
					  {
						trace(0,getClass().getName(),"Stream error :"+currentFileOrURL+", "+uafe.getMessage());
					  }
					  catch (LineUnavailableException lue)
					  {
						trace(0,getClass().getName(),"Stream error :"+currentFileOrURL+", "+lue.getMessage());
					  }
					  catch (IOException ex)
					  {
						trace(0,getClass().getName(),"Stream error :"+currentFileOrURL+", "+ex.getMessage());
					  }
                	theSoundPlayer.startPlayback();
                	theSoundPlayer.setGain( ((double)gainValue / (double)maxGain) );
					theSoundPlayer.setPan((float)balanceValue);
                	sampleRateImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, ""+Math.round((theSoundPlayer.getAudioFormat()).getSampleRate()/1000))).getBanner();
                	bitsRateImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, ""+Math.round((theSoundPlayer.getAudioFormat()).getFrameSize()*8*(theSoundPlayer.getAudioFormat()).getFrameRate()/1000))).getBanner();
                	offScreenGraphics.drawImage(sampleRateImage, sampleRateLocation[0], sampleRateLocation[1], this);
                	offScreenGraphics.drawImage(bitsRateImage, bitsRateLocation[0], bitsRateLocation[1], this);
                	if ((theSoundPlayer.getAudioFormat()).getChannels() == 2)
                	{
                	    offScreenGraphics.drawImage(activeModeImage[0], stereoLocation[0], stereoLocation[1], this);
                	}
                	else if ((theSoundPlayer.getAudioFormat()).getChannels() == 1)
                	{
                	    offScreenGraphics.drawImage(activeModeImage[1], monoLocation[0], monoLocation[1], this);
                	}
                	double lenghtInSecond = 0.0;
                	if ((theSoundPlayer.getAudioFileFormat()).getFrameLength() != -1 ) lenghtInSecond = ((theSoundPlayer.getAudioFileFormat()).getFrameLength()*theSoundPlayer.getAudioFormat().getFrameSize()*8)/((theSoundPlayer.getAudioFormat()).getFrameSize()*8*(theSoundPlayer.getAudioFormat()).getFrameRate());
                	else lenghtInSecond = ((theSoundPlayer.getAudioFileFormat()).getByteLength()*8)/((theSoundPlayer.getAudioFormat()).getFrameSize()*8*(theSoundPlayer.getAudioFormat()).getFrameRate());
                	int    minutes = (int) (lenghtInSecond/60);
                	int    seconds = (int) (lenghtInSecond - (minutes*60));
                	titleText = currentSongName.toUpperCase();
                	if (seconds >= 10) titleText = titleText + " ("+minutes+":"+seconds+")";
                	else titleText = titleText + " ("+minutes+":0"+seconds+")";
                	titleImage = (new taftb(fontIndex, imText, fontWidth, fontHeight, 0, titleText)).getBanner(0,0,155,6);
                	offScreenGraphics.drawImage(clearImage, titleLocation[0], titleLocation[1], this);
                	offScreenGraphics.drawImage(titleImage, titleLocation[0], titleLocation[1], this);
                	offScreenGraphics.drawImage(timeImage[0], minuteDLocation[0], minuteDLocation[1], this);
                	offScreenGraphics.drawImage(timeImage[0], minuteLocation[0], minuteLocation[1], this);
                	offScreenGraphics.drawImage(timeImage[0], secondDLocation[0], secondDLocation[1], this);
                	offScreenGraphics.drawImage(timeImage[0], secondLocation[0], secondLocation[1], this);

                	playerState = PLAY;
                	offScreenGraphics.drawImage(iconsImage[0], iconsLocation[0], iconsLocation[1], this);
                	offScreenGraphics.drawImage(iconsImage[3], iconsLocation[2], iconsLocation[3], this);
                	repaint();

                	trace(1,getClass().getName(),titleText);
                	if ((theSoundPlayer.getAudioFileFormat()).getFrameLength() != -1 ) trace(1,getClass().getName(),"Frames = "+(theSoundPlayer.getAudioFileFormat()).getFrameLength());
                	trace(1,getClass().getName(),"FrameRate (Hz) = "+theSoundPlayer.getAudioFormat().getFrameRate());
                	trace(1,getClass().getName(),"FrameSize (bits) = "+theSoundPlayer.getAudioFormat().getFrameSize()*8);
				}
            }
        }

        /*-----------------------------------*/
        /*-- Pause/Resume the current File --*/
        /*-----------------------------------*/
        else if (e.getActionCommand().equals("Pause"))
        {
            if (playerState == PLAY)
            {
                theSoundPlayer.pausePlayback();
                playerState = PAUSE;
                offScreenGraphics.drawImage(iconsImage[1], iconsLocation[0], iconsLocation[1], this);
				offScreenGraphics.drawImage(iconsImage[4], iconsLocation[2], iconsLocation[3], this);
                repaint();
            }
            else if (playerState == PAUSE)
            {
                theSoundPlayer.resumePlayback();
                playerState = PLAY;
                offScreenGraphics.drawImage(iconsImage[0], iconsLocation[0], iconsLocation[1], this);
                offScreenGraphics.drawImage(iconsImage[3], iconsLocation[2], iconsLocation[3], this);
                repaint();
            }
        }

        /*------------------*/
        /*-- Stop to play --*/
        /*------------------*/
        else if (e.getActionCommand().equals("Stop"))
        {
            if ( (playerState == PAUSE) || (playerState == PLAY))
            {
                theSoundPlayer.stopPlayback();
                playerState = STOP;
                secondsAmount = 0;
                acPosBar.setLocation(posBarBounds[0],posBarLocation[1]);
                offScreenGraphics.drawImage(iconsImage[2], iconsLocation[0], iconsLocation[1], this);
				offScreenGraphics.drawImage(iconsImage[4], iconsLocation[2], iconsLocation[3], this);
                repaint();
            }
        }

        /*----------*/
        /*-- Next --*/
        /*----------*/
        else if (e.getActionCommand().equals("Next"))
        {
           	// Try to get next song from the playlist
           	playlist.nextCursor();
           	PlaylistItem pli = playlist.getCursor();
			this.setCurrentSong(pli);
        }

        /*--------------*/
        /*-- Previous --*/
        /*--------------*/
        else if (e.getActionCommand().equals("Previous"))
        {
           	// Try to get previous song from the playlist
           	playlist.previousCursor();
           	PlaylistItem pli = playlist.getCursor();
			this.setCurrentSong(pli);
        }

        /*--------------------------------------------*/
        /*--     Exit window through Exit Button    --*/
        /*--------------------------------------------*/
        else if (e.getActionCommand().equals("Exit"))
        {
            if ( (playerState == PAUSE) || (playerState == PLAY))
            {
			 	theSoundPlayer.stopPlayback();
			}
            dispose();
            System.gc();
            System.exit(0);
        }
        /*--------------------------------------------*/
        /*-- Move full window through its Title Bar --*/
        /*--------------------------------------------*/
        else if (e.getActionCommand().equals("TitleBar"))
        {
            //trace(3,getClass().getName(),"X="+acTitle.getMouseX()+" Y="+acTitle.getMouseY());
            if (acTitleBar.isMousePressed() == false) FirstDrag = true;
            else
            {
        		int DeltaX = 0;
    	    	int DeltaY = 0;
	        	if (FirstDrag == false)
	        	{
	    	    	DeltaX = acTitleBar.getMouseX() - XDrag;
	    		    DeltaY = acTitleBar.getMouseY() - YDrag;
	    		    XDrag = acTitleBar.getMouseX() - DeltaX;
	    	        YDrag = acTitleBar.getMouseY() - DeltaY;
	    		    OrigineX = OrigineX + DeltaX;
		    	    OrigineY = OrigineY + DeltaY;
		    	    setLocation(OrigineX,OrigineY);
		        }
    		    else
	    	    {
		        	FirstDrag = false;
		        	XDrag = acTitleBar.getMouseX();
    		        YDrag = acTitleBar.getMouseY();
	    	    }
	    	}
        }
        else
        {

        }
    }


    public void paint(Graphics g)
    {
		if (offScreenImage != null)
        {
 	  		g.drawImage(offScreenImage, 0, 0, this);
        }
    }

	public void update(Graphics g)
	{
		//System.out.println("Update");
		paint(g);
    }

	/*-- Invoked when the mouse has been clicked on a component --*/
	//public void mouseClicked(MouseEvent me)
	//{}

	/*-- Invoked when the mouse enters a component --*/
	//public void mouseEntered(MouseEvent me)
	//{}

	/*-- Invoked when the mouse exits a component --*/
	//public void mouseExited(MouseEvent me)
	//{}

	/*-- Invoked when a mouse button has been pressed on a component --*/
 	//public void mousePressed(MouseEvent me)
	//{}

	/*-- Invoked when a mouse button has been released on a component --*/
 	//public void mouseReleased(MouseEvent me)
	//{}

	//public void mouseDragged(MouseEvent me)
	//{}

	//public void mouseMoved(MouseEvent me)
	//{}

    private File openFile(String file)
    {
		return new File(file);
	}

    public void setSkin(String sk)
    {
        thePath=sk;
    }

	/**
	 * Sends traces to Debug.
	 */
	private void trace(int level, String msg1, String msg2)
	{
		Debug dbg = Debug.getInstance();
		dbg.log(level,msg1+":"+msg2);
	}

	/**
	 * Entry point.
	 */
	public static void main(String[] args)
	{
        Player theGUI;
        String currentArg = null;
        String currentValue = null;
		String skin = null;
		String logfile = null;
		int loglevel = 0;
        for (int i=0;i<args.length;i++)
        {
			currentArg = args[i];
			if (currentArg.startsWith("-"))
			{
				if (currentArg.toLowerCase().equals("-skin"))
				{
					i++;
					if (i >= args.length) usage("skin value missing");
					currentValue = args[i];
					skin = currentValue.replace('\\', '/').replace('/',java.io.File.separatorChar);
				}
				else if (currentArg.toLowerCase().equals("-loglevel"))
				{
					i++;
					if (i >= args.length) usage("loglevel value missing");
					currentValue = args[i];
					try
					{
						loglevel = Integer.parseInt(currentValue);
					} catch (NumberFormatException nfe)
					  {
						  usage("Invalid number : "+nfe.getMessage());
					  }
				}
				else if (currentArg.toLowerCase().equals("-logfile"))
				{
					i++;
					if (i >= args.length) usage("logfile value missing");
					currentValue = args[i];
					logfile = currentValue.replace('\\', '/').replace('/',java.io.File.separatorChar);
				}
				else usage("Unknown parameter : "+currentArg);
			}
			else
			{
				usage("Invalid parameter :"+currentArg);
			}
		}
        theGUI= new Player(skin, loglevel, logfile);
		theGUI.show();
	}

	/**
	 * Displays usage.
	 */
	private static void usage(String msg)
	{
		System.out.println("jlGui 2.0 : "+msg);
		System.out.println("");
		System.out.println("jlGui 2.0 : Usage");
		System.out.println("            java javazoom.jlGui.Player [-skin skinFilename] [-loglevel number] [-logfile logFilename]");
		System.out.println("");
		System.out.println("            skinFilename : Filename to a Winamp Skin2.x");
		System.out.println("            number       : Level of traces (0,1,2)");
		System.out.println("            logFilename  : Filename for traces");
		System.out.println("");
		System.out.println("Homepage  : http://www.javazoom.net");
		System.exit(0);
	}
}
